#include "widget.h"
#include "ui_widget.h"
#include <QTcpSocket>
#include <functional>
#include <QMessageBox>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    // 1.设置窗口标题
    this->setWindowTitle("服务器");
    // 2.获取tcpServer实例 -- 添加到对象树
    server = new QTcpServer(this);
    // 3.连接信号槽，处理客户端连接
    connect(server, &QTcpServer::newConnection, this, &Widget::connectProcess);
    // 4.开始监听
    bool ret = server->listen(QHostAddress::Any, 9090);
    if(!ret){
        QMessageBox::critical(nullptr, "listen error", server->errorString());
        exit(1);
    }
}

Widget::~Widget()
{
    delete ui;
}

// 处理新的客户端连接
void Widget::connectProcess()
{
    // 1.获取新的客户端连接 -- 服务器这里的客户端连接不加入对象树, 客户端退出后手动销毁
    QTcpSocket* socket = server->nextPendingConnection();
    // 2.打印客户端登录日志
    QString log = "客户端[" + socket->peerAddress().toString() + ":" + QString::number(socket->peerPort()) + "] 上线";
    ui->listWidget->addItem(log);
    // 3.连接信号槽，处理客户端请求
    connect(socket, &QTcpSocket::readyRead, this, std::bind(&Widget::requestProcess,this, socket));
    // 4.连接信号槽，处理客户端退出
    connect(socket, &QTcpSocket::disconnected, this, [&](){
        // 销毁客户端 -- 直接delete是下册，更好一些的做法是使用 deleteLater
        QString log = "客户端[" + socket->peerAddress().toString() + ":" + QString::number(socket->peerPort()) + "] 下线";
        ui->listWidget->addItem(log);
        socket->deleteLater();
    });
}

void Widget::requestProcess(QTcpSocket* socket)
{
    // 1.获取请求
    QString request = socket->readAll();
    // 2.处理请求
    const QString &response = [&request](){
      return request;
    }();
    // 3.发送响应
    socket->write(response.toUtf8());
    // 4.打印日志
    QString log = "[" + socket->peerAddress().toString() + ":" + QString::number(socket->peerPort()) + "] "
            + "req: " + request + ", resp: " +response;
    ui->listWidget->addItem(log);
}

